/*****************************************************************************
 *                                                                           *
 *  IFT3330 - A06 - TP2                                                      *
 *                                                                           *
 *  20 novembre 2006                                                         *
 *                                                                           *
 *  par Nicola Grenon                                                        *
 *      GREN30077303                                                         *
 *      grenonni                                                             *
 *                                                                           *
 *    Dans le cadre d'un processus de creation d'un mecanisme d'inference    *
 * par chainage avant ou arriere, seront ici definis les objets qui seront   *
 * utilises par les deux macanismes.                                         *
 *    Les procedures communes et les utilitaires seront egalement presentes  *
 * dans ce fichier.                                                          *
 *                                                                           *
 * A NOTER: Les classes Fait, Regle et KB sont toutes controlees de facon    *
 *          statique, c'est-a-dire que le constructeur est prive et cache    *
 *          par une methode statique qui gere une liste interne a la classe. *
 *                                                                           *
 *****************************************************************************/


/* Importations */
package ChainArriere;
import java.io.*;			// Pour lire les fichiers
import java.util.*;			// Pour les Vector


/* La base de donnees.
   Contient la liste des faits et la liste des regles. */

class KB 
{

	/* Partie dynamique pour gerer l'unicite et la creation */

	static private KB kb;		// La seule kb qui sera en fonction

	// Pour creer la KB la premiere fois
	static public KB get() {
		if (kb == null) kb = new KB();
		return kb;
	}

	// Lire un ensemble de regles depuis un fichier
	static public KB lire(String fichier) {

		// Initialisation a vide
		KB kb = KB.get();
		String ligne;

		// Lecture du fichier (protegee)
		try {
			BufferedReader entree = new BufferedReader(new FileReader (fichier));
			ligne = entree.readLine();
			while (ligne != null) {
				
				// On nettoi un peu
				ligne = ligne.trim();	
		
				// Pour chaque ligne utile du fichier
				if (ligne.compareTo("") != 0 && ligne.charAt(0) != '%') {

					if (ligne.split(":").length < 2)	// Regle
					{
						kb.addRegle(ligne.trim());		// On ajoute la regle					
					}
					else								// Questons
					{							
						kb.addQuestions(ligne.split(":")[1].trim());							
					}
				}
			
				
				// Ligne suivante
				ligne = entree.readLine();

			}
			entree.close();

		} catch (Exception e) {
			System.out.println("Incapable de lire le fichier " + fichier + e+"\n");
		}

		return kb;
	}


	/* Partie dynamique */

	private Vector faits;		// La liste des faits ...
	private Vector regles;		// La liste des regles d'inferences connues
	private Vector questions;	// La liste des questions pertientes

	// Le constructeur	[ prive!!! - Utiliser KB.get() ]
	private KB() {
		faits = Fait.getListe();	// Les items sont gardes dans les classes
		regles = Regle.getListe();	// ... mais lies ici pour le cote pratique.
		questions = new Vector();
	}

	// Pour ajouter des regles
	public void addRegle(String texte) 
	{
		Regle regle = new Regle(texte);		
		regles.add(regle);
	}

	// Pour ajouter des questions (faits sur lesquels on peut interroger)
	public void addQuestions(String texte) {
		String liste[] = texte.split(" ");

		// On creer les faits et on les ajoute a la liste des questions
		for (int i = 0; i < liste.length; i++)
		{
			questions.add(Fait.creer(liste[i].trim()));
		}
	}

	// Pour ajouter des faits en lot (comme etant vrais)
	public void addFaitsVrais(String texte) {
		String liste[] = texte.split(" ");
		boolean val;
		String tmp;

		// On cree les faits et on les ajoute a la liste des questions
		for (int i = 0; i < liste.length; i++) {
			tmp = liste[i];
			val = true;

			// Terme negatif
			if (tmp.length() > 4 && tmp.substring(0,3).equals("NOT")) {
				val = false;
				tmp = tmp.substring(4,tmp.length()-1);				
			}

			Fait fait = Fait.creer(tmp);
			fait.set(val, null);
			faits.add(fait);
		}
	}
	
	// Pour ajouter des memoire de travail
	public void addMemoireDeTravail(String texte)
	{
		
			for (int i = 0; i < faits.size(); i++) 
			{				
				String temp = ((Fait)faits.elementAt(i)).libelle;
				
				if(temp.equals(texte))
				{
					((Fait)faits.elementAt(i)).determination = true;
					((Fait)faits.elementAt(i)).valeur = true;
				}
			}			
	}

	// Pour obtenir la liste des questions
	public Vector ask() {
		return questions;
	}

	// Pour obtenir la liste des regles
	public Vector rules() {
		return regles;
	}

}




